package utils;



import java.sql.ResultSet;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtils {


    public static String trimSpace(String str) {
        if(str != null){
            return str.replaceAll("\\t|\\r|\\n", " ");
        } else return "";
    }

    // 中文空格 != \s
    public static String trimBlank(String str){
        if(str != null) {
            return str.replaceAll("\\s+|　+", "");
        } else return "";
    }

    public static String trimOtherChar(String str){
        return str.replaceAll("[a-zA-Z:：、?]", "");
    }

    public static String trimOtherChars2(String str){
        return str.replaceAll("[{}]", "");
    }

    public static String findLastPeriodSplitter(String inputStr){
        String[] tmpList = inputStr.split("。");
        return tmpList[tmpList.length-1];
    }

    public static String findJudgeString(String inputStr){
        String regex = "(审判长|审判员|代理审判员)(\\S{1,5}?)((审判员|代理审判员|陪审员|人民陪审员|人民评审员)(\\S{0,5}?)){0,5}(二)";
        Matcher matcher = Pattern.compile(regex).matcher(inputStr);
        String matchString = "";
        if (matcher.find()){
            matchString = matcher.group(1)+ "-"+ matcher.group(2);
        }
        return matchString;
    }

    public static String extractJudgeTypeString(String inputStr){
        return StringUtils
                .findJudgeString(StringUtils.trimOtherChar(StringUtils.trimBlank(inputStr)));
    }

    public static List<String> findLawStrings(String input) {
        String regex = "(?<=[《〈（])中华人民共和国\\S{1,30}?(?=[）》〉])|(第[零一二三四五六七八九十百千]{1,7}?条)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);
        List<String> resList = new ArrayList<>();
        String lawPrefix = "";
        while(matcher.find()){
            String str = matcher.group();
            if(str.startsWith("中华人民共和国")){
                lawPrefix = str;
            } else if (!lawPrefix.equals("")){
                resList.add(lawPrefix + "_" + str);
            }
        }
        return resList;
    }


    public static List<String> findBaseLawList(String content){
        String regex = "([《〈（])(中华人民共和国\\S{1,30}?)([）》〉])(第[零一二三四五六七八九十百千]{1,7}?条)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(trimBlank(content));
        List<String> resList = new ArrayList<>();
        while(matcher.find()){
            resList.add(matcher.group(2)+matcher.group(4));
        }

        return resList;
    }

    // 中文空格 != \s, replaceAll
    // resList[0] = tableStrs ,   resList[1] = contentStrs
    public static List<String> extractLawTableAndContent(String input) {
        //String regex = "(?<=　)(第一[编章节]).+?(?=\\1)";
        String allStr = input.replaceAll("　", " ");
        String regex = "(?<=\\s)(第一[编章节]).+?(?=\\1)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(allStr);
        // skip table list, find law content
        String regex2 = "第一[编章节]";
        Pattern pattern2 = Pattern.compile(regex2);
        Matcher matcher2 = pattern2.matcher(allStr);


        List<String> resList = new ArrayList<>();
        StringBuffer tableListStr = new StringBuffer();

        if (matcher.find()) {
            String tableRawListStr = matcher.group();
            String regex3 = "(第[零一二三四五六七八九十百千]{1,7}?[编章节])(\\s\\S+?){1,2}(?=[第|\\s|$])";
            Pattern pattern3 = Pattern.compile(regex3);
            Matcher matcher3 = pattern3.matcher(tableRawListStr);
            while(matcher3.find()){
                tableListStr.append(matcher3.group());
            }
            String tableStrs = trimBlank(tableListStr.toString());
            resList.add(tableStrs);
            String contentStr = trimBlank(allStr.substring(matcher.end()));
            resList.add(contentStr);
        } // not law table found !
        else if (matcher2.find()) {
            resList.add("");
            String contentStr = trimBlank(allStr.substring(matcher2.start()));
            resList.add(contentStr);
        }
        else {
            resList.add("");
            resList.add(trimBlank(allStr));
        }

        return resList;
    }


    // index-lev-name
    public static List<String> extractLawTableList(String input) {
        List<String> itemList = new ArrayList<>();
        //String regex = "(第[零一二三四五六七八九十百千]{1,7}?)([编章节])　(\\S+?)(?=[　$])";
        String regex = "(第[零一二三四五六七八九十百千]{1,7}?)([编章节])(\\S+?)(?=$|第[零一二三四五六七八九十百千]{1,7}?[编章节])";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);
        while (matcher.find()) {
            String itemIndex = matcher.group(1);
            String itemLev = matcher.group(2);
            String itemName = matcher.group(3);
            String fixedName = replaceUnregular(trimTableName(itemName));
            String itemStr = itemIndex +"-"+ itemLev + "-" + fixedName;
            itemList.add(itemStr);
        }

        return itemList;
    }



    // check law_id: 308, 576, 893, 1102
    public static String trimTableString(String input) {
        String trimWord1 = "序言";
        String trimWord2 = "第一条";
        String trimWord3 = "现公布";
        String trimWord4 = "《";
        String trimWord5 = "经2003年";

        String[] trimWords = {""};
        String trimmedInput = input;
        for(String word: trimWords){
            if(trimmedInput.contains(word)) trimmedInput = trimmedInput.substring(0, trimmedInput.lastIndexOf(word));
        }

        return input
                .split(trimWord1)[0]
                .split(trimWord2)[0]
                .split(trimWord3)[0]
                .split(trimWord4)[0]
                .split(trimWord5)[0];
    }

    // check law_id: 20, 304
    static String trimTableName(String matcherName){
        String[] trimWords = {"总则", "附则", "分则"};
        String trimmedName = matcherName;
        for(String word: trimWords){
            if(!matcherName.equals(word) && matcherName.contains(word))
                trimmedName = trimmedName.replaceAll(word, "");
        }
        return trimmedName;
    }

    // replace () -> （）
    static String replaceUnregular(String content){
        return content.replaceAll("\\(", "（").replaceAll("\\)", "）");
    }

    // String to Law table Map
    public static Map<String, Object> extractLawMap(String str){
        List<String> strList = Arrays.asList(str.split(">>"));
        assert strList.size() >= 2;
        String name = String.join("", strList).replaceAll("-", "");
        String content = strList.get(strList.size() - 1);
        String belongs_law = String.join("", strList.subList(0, strList.size() - 1)).replaceAll("-", "");
        Map<String, Object> prop = new HashMap<>();
        prop.put("belongs_law", belongs_law);
        prop.put("name", name);
        prop.put("content", content);
        prop.put("level", 1);
        return prop;
    }


    public static List<String> extractLawClause(String contentBlock) {
        String regex = "(第[零一二三四五六七八九十百千]{1,7}?条(之[一二三四五六七八九])?)(.+?[。|\\}])(?=第[零一二三四五六七八九十百千]{1,7}?|\\Z)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(contentBlock);
        List<String> resList = new ArrayList<>();
        if(!contentBlock.equals("")){
            while(matcher.find()){
                String str;
                str = matcher.group(1)+ "-" + matcher.group(3);
                resList.add(str);
            }
        }
        return resList;
    }



    // NOTE: prefix + >> + split
    public static List<String> generateSplitList(List<String> tableList) {
        List<String> splitterList = new ArrayList<>();
        String splitPrefix;
        if(!tableList.isEmpty()){
            for(String item: tableList){
                if(checkFirstSeq(item)){
                    if(splitterList.isEmpty()){
                        splitterList.add(item.replaceAll("-",""));
                    } else {
                        splitPrefix = splitterList.get(splitterList.size()-1);
                        String splitter = splitPrefix + item.replaceAll("-","");
                        splitterList.set(splitterList.size()-1, splitter);
                    }
                } else {
                    splitterList.add(item.replaceAll("-",""));
                }
            }
        }
        return splitterList;
    }

    // lawPrefix process () or not?
    public static List<String> generateExtendList(String lawTitle, List<String> tableList){
        List<String> extendedList = new ArrayList<>();
        Map<String, String> extendPrefix = new HashMap<>();
        String lawPrefix = lawTitle;
        if(!tableList.isEmpty()) {
            // seq: itemArr[0], level: itemArr[1], content: itemArr[2]
            String[] firstItemArr = tableList.get(0).split("-");
            extendPrefix.put(firstItemArr[1], lawPrefix);
            extendedList.add(lawPrefix + ">>" + tableList.get(0).replaceFirst("-", ""));
            for (int i = 1; i < tableList.size(); i++) {
                String item = tableList.get(i);
                String preItem = tableList.get(i - 1);
                String[] itemArr = item.split("-");
                String[] preItemArr = preItem.split("-");
                if (!checkSameLevel(item, preItem)) {
                    if (checkFirstSeq(item))
                        extendPrefix.put(itemArr[1], extendPrefix.get(preItemArr[1]) + ">>" + preItem.replaceFirst("-", ""));
                    extendedList.add(extendPrefix.get(itemArr[1]) + ">>" + item.replaceFirst("-", ""));
                } else {
                    extendedList.add(extendPrefix.get(itemArr[1]) + ">>" + item.replaceFirst("-", ""));
                }
            }
        }
        return  extendedList;
    }
    // lawContent trim blank
    // splitItem : lawClauseList
    // TODO: fix malformed title split, check law 3970
    public static List<List<String>> splitLawContentByList(String lawTitle, String lawContent, List<String> splitList){
        List<List<String>> lawClauseList = new ArrayList<>();
        if(!splitList.isEmpty()){
            for(int index = 0; index<=splitList.size()-1; index++){
                int start = 0;
                String startItem = splitList.get(index);
                int splitLength = splitList.get(index).length();
                int end = lawContent.length();
                String contentBlock = "";

                if(lawContent.contains(startItem)){
                    start = lawContent.indexOf(startItem);
                    if(index+1<splitList.size() && lawContent.contains(splitList.get(index + 1))){
                        end = lawContent.indexOf(splitList.get(index + 1));
                        contentBlock = lawContent.substring(start+splitLength, end);
                    } else if (index+1 == splitList.size()){
                        contentBlock = lawContent.substring(start+splitLength, end);
                    } else if (!lawContent.contains(splitList.get(index + 1))){
                        System.err.println("split content failed! : " + splitList.get(index + 1));
                    }
                } else {
                    System.err.println("split content failed! : " + startItem);
                }

                lawClauseList.add(extractLawClause(contentBlock));
            }
            // check split size equal clause list
            if( splitList.size() != lawClauseList.size())
                System.err.println(lawTitle+ " split size and clause list not equal!");
        } else {
            // split size = 0, clause list = 1
            lawClauseList.add(extractLawClause(lawContent));
        }

        return lawClauseList;
    }

    public static boolean checkFirstSeq(String inputItem) {
        return (inputItem.split("-")[0].equals("第一"));
    }

    public static boolean checkSameLevel(String item1, String item2) {
        String[] arr1 = item1.split("-");
        String[] arr2 = item2.split("-");
        return arr1[1].equals(arr2[1]);
    }

    public static String extractBriefTitle(String lawTitle) {
        String regex = "《(\\S+)》";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(lawTitle);
        if(lawTitle.startsWith("中华人民共和国")) return lawTitle.replaceAll("（\\S+）", "");
        else if(matcher.find()){
           return matcher.group(1);
        } else {
            return lawTitle;
        }
    }

    // DO NOT put large text in single node.
    public static Map<String, String> getDataFromResultSet(ResultSet resultSet) throws Exception{
        String doc_id = StringUtils.trimSpace(resultSet.getString(1));
        String url = StringUtils.trimSpace(resultSet.getString(2));
        String title = StringUtils.trimSpace(resultSet.getString(3));
        //String content = StringUtils.trimSpace(resultSet.getString(4));
        String judgement_date = StringUtils.trimSpace(resultSet.getString(6));
        String pub_date = StringUtils.trimSpace(resultSet.getString(7));
        String create_time = StringUtils.trimSpace(resultSet.getString(8));
        String case_num = StringUtils.trimSpace(resultSet.getString(9));
        String trial_procedures = StringUtils.trimSpace(resultSet.getString(10));
        String case_type = StringUtils.trimSpace(resultSet.getString(11));
        String court_name = StringUtils.trimSpace(resultSet.getString(12));
        Map<String, String> node_prop = new HashMap<>();
        node_prop.put("doc_id", doc_id);
        node_prop.put("url", url);
        node_prop.put("title", title);
        //node_prop.put("content", content);
        node_prop.put("judgement_date", judgement_date);
        node_prop.put("pub_date", pub_date);
        node_prop.put("case_num", case_num);
        node_prop.put("create_time", create_time);
        node_prop.put("trial_procedures", trial_procedures);
        node_prop.put("case_type", case_type);
        node_prop.put("court_name", court_name);
        return node_prop;
    }

    // split content based on regex
    public static String trimJudgementContent(String rawContent) {
        String regex = "(审判长|审判员|代理审判员)(\\S{1,5}?)((审判员|代理审判员|陪审员|人民陪审员|人民评审员)(\\S{0,5}?)){0,5}(二)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(rawContent);
        if(matcher.find()){
            int start_idx = matcher.start();
            return rawContent.substring(0, start_idx);
        }
        else
            return rawContent;
    }

}
